package stars;

import eventManager.EventManager;
import galaxies.enums.EGalaxyAge;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

import old.coordinate.CoordinateModel;

import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetManager;
import com.jme3.math.Vector2f;
import com.jme3.scene.Spatial;

import stars.enums.EStarDistribution;
import stars.enums.EStarType;
import stars.enums.StarColors;
import stars.enums.StarDistributions;
import stars.enums.StarParameters;
import utilities.MVCMaker;
import view.EViewList;
import view.AbstractView;
import view.IView;
import view.ViewModule;





//Uses StarDistribution values to generate a given number of stars via StarFactory
public class StarGenerator {
	
//	int starTypes = 13;
//	double[][] cumuProbs = new double[starTypes+1][3];
	private Random rand = new Random();
	
	private StarModelBuilder modelFact;
	public StarModel model;
	
	private StarViewBuilder viewFact;
	private ViewModule views;
	
//	private ArrayList<StarController> stars = new ArrayList<StarController>();
//	private StarController controller;
//	private StarControllerBuilder controllerFact;
	
	private ArrayList<StarControl> stars = new ArrayList<StarControl>();
	private StarControl control;
	private StarControlBuilder controlFact;
	
	//private StarDistributions starDists;
	private StarParameters starParams;
	//private StarColors starColors;
	
	public StarGenerator(StarParameters starParams){		
		//this.starDists = starDists;
		this.starParams = starParams;
		//this.starColors = starColors;
		//calcProbs();
	}
	
//	//Create a single star of a set type
//	public StarController genSingleStar(String type) {
//		
//		StarController tempController;
//		tempController = buildMVC(type, starParams);
//
//		return tempController;
//	}
	
	//Create a single star of either a particular type or a random type given a galaxy age
	public StarControl createSingleStar(String ageOrType) { //, int[] hexLocation, Vector2f systemLocation) {
		StarControl tempControl;
		modelFact = new StarModelBuilder(); 
		viewFact = new StarViewBuilder();
		controlFact = new StarControlBuilder();
		if (!starParams.getEntries().contains(ageOrType)) {
			//an age parameter has been sent in, so randomly determine type
			String type = randomType(ageOrType, starParams);
			tempControl = buildMVC(type);
		}
		else {//a type parameter has been sent in, so build directly
			tempControl = buildMVC(ageOrType);
		}
		
		return tempControl;
	}
	
	//Create multiple stars of random types based on galaxy age distribution
	public ArrayList<StarControl> createStars(String age, int numStars)
	{		
		String type;
		StarControl tempControl;
		modelFact = new StarModelBuilder(); 
		viewFact = new StarViewBuilder();
		controlFact = new StarControlBuilder();
		for (int j = 0; j < numStars; j++)
		{
			type = randomType(age, starParams);			
			tempControl = buildMVC(type);			
			stars.add(tempControl);
		}
		
		return stars;		
	}
	
	private StarControl buildMVC(String type) {
		
		double temperature = randomTemperature(type, starParams);
		
		model = modelFact.createMStar(temperature, type, starParams);
		views = viewFact.buildViews(model, modelFact.features, starParams);
		control = controlFact.createControl(model, modelFact.features, views);
		
//		MVCMaker.linkElements(model, views, controller);
		
		return control;
	}
	
	private String randomType(String age, StarParameters starParameters) {
		double prob = rand.nextDouble();
		
		HashMap<String, Double> distribution = starParameters.getAllProbabilities(age);
		
		Set<String> entries = distribution.keySet();
		String currEntry;
		String lastEntry = "MSRED";
		
		double cumuProb = 0.0;
		for (Iterator<String> i = entries.iterator(); i.hasNext();) {
			currEntry = i.next();
			cumuProb+=distribution.get(currEntry);
			
			if (cumuProb > prob) {
				return currEntry;
			}
		}
		
		return lastEntry; //in case the type probabilities don't equal 1, algorithm returns MSRED
		
		
		
		
//		
//		
//		
//		int column;
//		int probIndex = -1;
//		EStarType type = EStarType.BLACKHOLE; //default to Blackhole
//		
//		if (age.equals(EGalaxyAge.YOUNG))
//			column = 0;
//		else if (age.equals(EGalaxyAge.AVERAGE))
//			column = 1;
//		else
//			column = 2;
//		
//		double value = rand.nextDouble();
//		
//		for (int i = 0; i < starTypes; i++)
//		{
//			if ((value - cumuProbs[i][column]) >= 0)
//			{
//				probIndex = i; //leaves value at last index > 0
//				type = EStarType.get(probIndex);					
//			}				
//		}		
//		
//		return type;
	}
	
	private double randomTemperature(String type, StarParameters starParams) {
		double maxTemp = starParams.getAllParameters().get(type).getMaxTemp();
		double minTemp = starParams.getAllParameters().get(type).getMinTemp();
		
		double tempRange = maxTemp - minTemp;
		double temperature = rand.nextDouble()*tempRange + minTemp;
		
		return temperature;		
	}
}